#include "ocl_cards.h"
#include "ocl_video.h"
#include <ogc/color.h>
#include <gccore.h>
#include <ogcsys.h>

//Images
#include "../gfx/card_face.h"
#include "../gfx/card_back.h"
#include "../gfx/heart.h"
#include "../gfx/club.h"
#include "../gfx/spade.h"
#include "../gfx/diamond.h"
#include "../gfx/jack.h"
#include "../gfx/queen.h"
#include "../gfx/king.h"

//Sounds
extern u8 dealwav[];
extern u8 coinwav[];
extern u8 winwav[];
extern u8 flipwav[];
extern u8 pushwav[];
//extern u8 casinowav[];

int flip_samples = 0;
int deal_samples = 0;
int coin_samples = 0;
int win_samples  = 0;
int push_samples = 0;
int casino_samples = 0;

int samplerate = 0;

int FONT_SIZE       = 2;

/****************************************************************************
* FLIP16 - Switch from LE to BE
****************************************************************************/
u16
FLIP16 (u16 value)
{
  return ((value & 0xff) << 8) | ((value & 0xff00) >> 8);
}

/****************************************************************************
* FLIP32 - Switch from LE to BE
****************************************************************************/
u32
FLIP32 (u32 value)
{
  u32 b;

  b = (value & 0xff) << 24;
  b |= (value & 0xff00) << 8;
  b |= (value & 0xff0000) >> 8;
  b |= (value & 0xff000000) >> 24;

  return b;
}

/****************************************************************************
* Windows WAV file header stuff
****************************************************************************/
typedef struct
{
  u32 RIFF;
  u32 riSize;
  u32 WAVE;
  u32 waFmt;
  u32 fmtSize;
  u16 fmtType;
  u16 fmtChannels;
  u32 fmtRate;
  u32 fmtSamplesPerSecond;
  u16 fmtBlockAlign;
  u16 fmtBitsPerSample;
  u16 fmtExtensionSize;
} __attribute__ ((__packed__)) WAVEHDR;

typedef struct
{
  u32 WAVEDATA;
  u32 waSize;
} __attribute__ ((__packed__)) WAVEDATAHDR;

/****************************************************************************
* CvtWave
*
* Convert PC (x86) WAVE to GC Raw Audio
****************************************************************************/
u32
CvtWave (char *wavebuffer)
{
  WAVEHDR wavhdr;
  WAVEDATAHDR datahdr;
  int samples;
  int i;
  u16 *src, *dst;

	/*** Capture the WAV file header ***/
  memcpy (&wavhdr, wavebuffer, sizeof (WAVEHDR));

	/*** Do some basic checking ***/
  if (memcmp (&wavhdr.RIFF, "RIFF", 4))
    return 0;

  if (memcmp (&wavhdr.WAVE, "WAVE", 4))
    return 0;

  if (memcmp (&wavhdr.waFmt, "fmt ", 4))
    return 0;

	/*** Important!
	 * Wave file must be type 1 == Uncompressed PCM
	 */
  if (FLIP16 (wavhdr.fmtType) != 1)
    return 0;

	/*** Looking good! - So capture the sample rate ***/
  samplerate = FLIP32 (wavhdr.fmtRate);
  if ((samplerate != 32000) && (samplerate != 48000))
    return 0;

	/*** Also need 2 channels ***/
  if (FLIP16 (wavhdr.fmtChannels) != 2)
    return 0;

	/*** Pickup the data header ***/
  memcpy (&datahdr, wavebuffer + 20 + FLIP32 (wavhdr.fmtSize), 8);

  if (memcmp (&datahdr.WAVEDATA, "data", 4))
    return 0;

  samples = FLIP32 (datahdr.waSize);
  samples >>= 1;

	/***
	 * NB: Sound data MUST be aligned to 32 bytes.
	 */
  src = (u16 *) wavebuffer + 28 + FLIP32 (wavhdr.fmtSize);
  dst = (u16 *) wavebuffer;

  for (i = 0; i < samples; i++)
    dst[i] = FLIP16 (src[i]);

  return samples << 1;
}

int CARDS_Init(CARDS_Ptr* out_ptr)
{
	out_ptr->SOUND_ENABLED = 0;

	return 0;
}

int CARDS_InitSound(CARDS_Ptr* in_ptr)
{
	in_ptr->SOUND_ENABLED = 1;

	AUDIO_Init(NULL);

	return 0;
}

void CARDS_Destruct(CARDS_Ptr* in_ptr)
{

   if(in_ptr->SOUND_ENABLED)
   {
  //      Mix_FreeChunk(in_ptr->deal_sound);
//	Mix_CloseAudio();
   }
}

void CARDS_PlayCasinoSound(const CARDS_Ptr* card_ptr)
{

}
void CARDS_StopCasinoSound(const CARDS_Ptr* card_ptr)
{
}

void CARDS_PlayDealSound(const CARDS_Ptr* card_ptr)
{

	if(card_ptr->SOUND_ENABLED)
	{
	  if(!deal_samples)
	  {
	     deal_samples = CvtWave (dealwav);

	     if (deal_samples)
	     {
	         if (samplerate == 48000)
	 	 	AUDIO_SetDSPSampleRate (AI_SAMPLERATE_48KHZ);
   	         else
			AUDIO_SetDSPSampleRate (AI_SAMPLERATE_32KHZ);

	      	  DCFlushRange (dealwav, deal_samples);
	     }
	  }

	  if(deal_samples)
 	  {
	     // AUDIO_InitDMA ((u32) dealwav, deal_samples);
	      //AUDIO_StartDMA ();
	      //while (AUDIO_GetDMABytesLeft ());
	      //AUDIO_StopDMA ();
	   }	
	}
}

void CARDS_PlayFlipSound(const CARDS_Ptr* card_ptr)
{


	if(card_ptr->SOUND_ENABLED)
	{
	  if(!flip_samples)
	  {
	     flip_samples = CvtWave (flipwav);

	     if (flip_samples)
	     {
	         if (samplerate == 48000)
	 	 	AUDIO_SetDSPSampleRate (AI_SAMPLERATE_48KHZ);
   	         else
			AUDIO_SetDSPSampleRate (AI_SAMPLERATE_32KHZ);

	      	  DCFlushRange (flipwav, flip_samples);
	     }
	  }

	  if(flip_samples)
 	  {
	      AUDIO_InitDMA ((u32) flipwav, flip_samples);
	      AUDIO_StartDMA ();
	      while (AUDIO_GetDMABytesLeft ());
	      AUDIO_StopDMA ();
	   }	
	}
}

void CARDS_PlayWinSound(const CARDS_Ptr* card_ptr)
{

	if(card_ptr->SOUND_ENABLED)
	{
	  if(!win_samples)
	  {
	     win_samples = CvtWave (winwav);

	     if (win_samples)
	     {
	         if (samplerate == 48000)
	 	 	AUDIO_SetDSPSampleRate (AI_SAMPLERATE_48KHZ);
   	         else
			AUDIO_SetDSPSampleRate (AI_SAMPLERATE_32KHZ);

	      	  DCFlushRange (winwav, win_samples);
	     }
	  }

	  if(win_samples)
 	  {
	      AUDIO_InitDMA ((u32) winwav, win_samples);
	      AUDIO_StartDMA ();
	      while (AUDIO_GetDMABytesLeft ());
	      AUDIO_StopDMA ();
	   }	
	}
}

void CARDS_PlayPushSound(const CARDS_Ptr* card_ptr)
{
	if(card_ptr->SOUND_ENABLED)
	{
	  if(!push_samples)
	  {
	     push_samples = CvtWave (pushwav);

	     if (push_samples)
	     {
	         if (samplerate == 48000)
	 	 	AUDIO_SetDSPSampleRate (AI_SAMPLERATE_48KHZ);
   	         else
			AUDIO_SetDSPSampleRate (AI_SAMPLERATE_32KHZ);

	      	  DCFlushRange (pushwav, push_samples);
	     }
	  }

	  if(push_samples)
 	  {
	      AUDIO_InitDMA ((u32) pushwav, push_samples);
	      AUDIO_StartDMA ();
	      while (AUDIO_GetDMABytesLeft ());
	      AUDIO_StopDMA ();
	   }	
	}
}

void CARDS_PlayCoinSound(const CARDS_Ptr* card_ptr)
{
	if(card_ptr->SOUND_ENABLED)
	{
	  if(!coin_samples)
	  {
	     coin_samples = CvtWave (coinwav);

	     if (coin_samples)
	     {
	         if (samplerate == 48000)
	 	 	AUDIO_SetDSPSampleRate (AI_SAMPLERATE_48KHZ);
   	         else
			AUDIO_SetDSPSampleRate (AI_SAMPLERATE_32KHZ);

	      	  DCFlushRange (coinwav, coin_samples);
	     }
	  }

	  if(coin_samples)
 	  {
	      AUDIO_InitDMA ((u32) coinwav, coin_samples);
	      AUDIO_StartDMA ();
	      while (AUDIO_GetDMABytesLeft ());
	      AUDIO_StopDMA ();
	   }	
	}
}

void CARDS_RenderDownCard(const CARDS_Ptr* card_ptr, const VIDEO_Ptr* video_ptr, CARDS_Card* card, int screen_x, int screen_y)
{
	int x = 0;
	int y = 0;

	if(card_ptr != NULL && video_ptr != NULL && card != NULL)
	{
	        x = screen_x - (card_back_width / 2);
	        y = screen_y - (card_back_high / 2);

		card->screen_loc_x = x;
		card->screen_loc_y = y;
		card->screen_loc_w = card_face_width;
		card->screen_loc_h = card_face_high;	

		OCL_VIDEO_RenderImage(video_ptr, &(card_back_img), card_back_width, card_back_high, x, y);  
	}
	else
	{
		printf("Error! Null value in CARDS_RenderDownCard\n");
	}
}

void CARDS_RenderCard(const CARDS_Ptr* card_ptr, const VIDEO_Ptr* video_ptr, CARDS_Card* card, int screen_x, int screen_y)
{
	void* suit;
	int suit_w, suit_h;

        int suit_loc_x, suit_loc_y, small_suit_loc_x, small_suit_loc_y, card_loc_x, card_loc_y;
        int card_center_x, card_center_y;
        unsigned short color;

        int offset=-20;
	int t_XO = 6;
	int b_XO = -14;
	int b_YO = -47;
	if(card_ptr != NULL && video_ptr != NULL && card != NULL)
	{

		color = BLACK;

		switch(card->suit)
		{
			case HEART:
				suit = &(heart_img);
				suit_w = heart_width;
				suit_h = heart_high;
		                color = RED;
				break;
			case CLUB:
				suit = &(club_img);
				suit_w = club_width;
				suit_h = club_high;
				color = BLACK;
				break;
			case SPADE:
				suit = &(spade_img);
				suit_w = spade_width;
				suit_h = spade_high;
				color = BLACK;
				break;
			case DIAMOND:
				suit = &(diamond_img);
				suit_w = diamond_width;
				suit_h = diamond_high;
		                color = RED;
				break;
		}

	     //DRAW CARD--------------------------------------------------
	      //draw card bg
		card_loc_x = screen_x - (card_face_width / 2);
		card_loc_y = screen_y - (card_face_high / 2);

		card->screen_loc_x = card_loc_x;
		card->screen_loc_y = card_loc_y;
		card->screen_loc_w = card_face_width;
		card->screen_loc_h = card_face_high;

		OCL_VIDEO_RenderImage(video_ptr, &(card_face_img), card_face_width, card_face_high, card_loc_x, card_loc_y);

		card_center_x = screen_x - (suit_w / 2); //draw centeRED
		card_center_y = screen_y - (suit_h / 2); //draw centeRED

	      //Draw center suits

		switch(card->value)
		{
		   case ACE:
		      suit_loc_x = card_center_x;
		      suit_loc_y = card_center_y;
		      OCL_VIDEO_RenderImage(video_ptr, suit, suit_w, suit_h, suit_loc_x, suit_loc_y);

		      OCL_VIDEO_RenderText(video_ptr, "A", FONT_SIZE, card_loc_x+t_XO, card_loc_y+offset, color, WHITE); 
		      OCL_VIDEO_RenderText(video_ptr, "A", FONT_SIZE, screen_x + card_face_width / 2 - FONT_SIZE+b_XO, card_loc_y+card_face_high - FONT_SIZE+b_YO,  color, WHITE); 
		      break;
		   case 2:
		      suit_loc_x = card_center_x;
		      suit_loc_y = card_center_y+suit_h+suit_h/2;
		      OCL_VIDEO_RenderImage(video_ptr, suit,  suit_w, suit_h, suit_loc_x, suit_loc_y);
		      suit_loc_x = card_center_x;
		      suit_loc_y = card_center_y-suit_h-suit_h/2;
		      OCL_VIDEO_RenderImage(video_ptr, suit,  suit_w, suit_h, suit_loc_x, suit_loc_y);

		      OCL_VIDEO_RenderText(video_ptr, "2", FONT_SIZE, card_loc_x+t_XO, card_loc_y+offset,  color, WHITE); 
		      OCL_VIDEO_RenderText(video_ptr, "2", FONT_SIZE, screen_x + card_face_width / 2 - FONT_SIZE+b_XO, card_loc_y+card_face_high - FONT_SIZE+b_YO,  color, WHITE); 
		      break;
		   case 3:
		      suit_loc_x = card_center_x;
		      suit_loc_y = card_center_y;
		      OCL_VIDEO_RenderImage(video_ptr, suit, suit_w, suit_h,  suit_loc_x, suit_loc_y);
		      suit_loc_x = card_center_x;
		      suit_loc_y = card_center_y+suit_h+suit_h/2;
		      OCL_VIDEO_RenderImage(video_ptr, suit, suit_w, suit_h,  suit_loc_x, suit_loc_y);
		      suit_loc_x = card_center_x;
		      suit_loc_y = card_center_y-suit_h-suit_h/2;
		      OCL_VIDEO_RenderImage(video_ptr, suit,  suit_w, suit_h, suit_loc_x, suit_loc_y);

		      OCL_VIDEO_RenderText(video_ptr, "3", FONT_SIZE, card_loc_x+t_XO, card_loc_y+offset,  color, WHITE); 
		      OCL_VIDEO_RenderText(video_ptr, "3", FONT_SIZE, screen_x + card_face_width / 2 - FONT_SIZE+b_XO, card_loc_y+card_face_high - FONT_SIZE+b_YO,  color, WHITE); 
		      break;
		   case 4:
		      suit_loc_x = card_center_x-suit_w;
		      suit_loc_y = card_center_y+suit_h+suit_h/2;
		      OCL_VIDEO_RenderImage(video_ptr, suit, suit_w, suit_h,  suit_loc_x, suit_loc_y);
		      suit_loc_x = card_center_x-suit_w;
		      suit_loc_y = card_center_y-suit_h-suit_h/2;
		      OCL_VIDEO_RenderImage(video_ptr, suit, suit_w, suit_h,  suit_loc_x, suit_loc_y);
		      suit_loc_x = card_center_x+suit_w;
		      suit_loc_y = card_center_y+suit_h+suit_h/2;
		      OCL_VIDEO_RenderImage(video_ptr, suit, suit_w, suit_h,  suit_loc_x, suit_loc_y);
		      suit_loc_x = card_center_x+suit_w;
		      suit_loc_y = card_center_y-suit_h-suit_h/2;
		      OCL_VIDEO_RenderImage(video_ptr, suit, suit_w, suit_h,  suit_loc_x, suit_loc_y);

		      OCL_VIDEO_RenderText(video_ptr, "4", FONT_SIZE, card_loc_x+t_XO, card_loc_y+offset,  color, WHITE);
		      OCL_VIDEO_RenderText(video_ptr, "4", FONT_SIZE, screen_x + card_face_width / 2 - FONT_SIZE+b_XO, card_loc_y+card_face_high - FONT_SIZE+b_YO,  color, WHITE); 
		      break;
		   case 5:
		      suit_loc_x = card_center_x;
		      suit_loc_y = card_center_y;
		      OCL_VIDEO_RenderImage(video_ptr, suit, suit_w, suit_h,  suit_loc_x, suit_loc_y);
		      suit_loc_x = card_center_x-suit_w;
		      suit_loc_y = card_center_y+suit_h+suit_h/2;
		      OCL_VIDEO_RenderImage(video_ptr, suit, suit_w, suit_h,  suit_loc_x, suit_loc_y);
		      suit_loc_x = card_center_x-suit_w;
		      suit_loc_y = card_center_y-suit_h-suit_h/2;
		      OCL_VIDEO_RenderImage(video_ptr, suit,  suit_w, suit_h, suit_loc_x, suit_loc_y);
		      suit_loc_x = card_center_x+suit_w;
		      suit_loc_y = card_center_y+suit_h+suit_h/2;
		      OCL_VIDEO_RenderImage(video_ptr, suit, suit_w, suit_h,  suit_loc_x, suit_loc_y);
		      suit_loc_x = card_center_x+suit_w;
		      suit_loc_y = card_center_y-suit_h-suit_h/2;
		      OCL_VIDEO_RenderImage(video_ptr, suit, suit_w, suit_h,  suit_loc_x, suit_loc_y);

		      OCL_VIDEO_RenderText(video_ptr, "5", FONT_SIZE, card_loc_x+t_XO, card_loc_y+offset,  color, WHITE);
		      OCL_VIDEO_RenderText(video_ptr, "5", FONT_SIZE, screen_x + card_face_width / 2 - FONT_SIZE+b_XO, card_loc_y+card_face_high - FONT_SIZE+b_YO,  color, WHITE); 
		      break;
		   case 6:
		      suit_loc_x = card_center_x-suit_w;
		      suit_loc_y = card_center_y;
		      OCL_VIDEO_RenderImage(video_ptr, suit, suit_w, suit_h,  suit_loc_x, suit_loc_y);
		      suit_loc_x = card_center_x+suit_w;
		      suit_loc_y = card_center_y;
		      OCL_VIDEO_RenderImage(video_ptr, suit, suit_w, suit_h,  suit_loc_x, suit_loc_y);
		      suit_loc_x = card_center_x-suit_w;
		      suit_loc_y = card_center_y+suit_h+suit_h/2;
		      OCL_VIDEO_RenderImage(video_ptr, suit,  suit_w, suit_h, suit_loc_x, suit_loc_y);
		      suit_loc_x = card_center_x-suit_w;
		      suit_loc_y = card_center_y-suit_h-suit_h/2;
		      OCL_VIDEO_RenderImage(video_ptr, suit,  suit_w, suit_h, suit_loc_x, suit_loc_y);
		      suit_loc_x = card_center_x+suit_w;
		      suit_loc_y = card_center_y+suit_h+suit_h/2;
		      OCL_VIDEO_RenderImage(video_ptr, suit,  suit_w, suit_h, suit_loc_x, suit_loc_y);
		      suit_loc_x = card_center_x+suit_w;
		      suit_loc_y = card_center_y-suit_h-suit_h/2;
		      OCL_VIDEO_RenderImage(video_ptr, suit, suit_w, suit_h,  suit_loc_x, suit_loc_y);

		      OCL_VIDEO_RenderText(video_ptr, "6", FONT_SIZE, card_loc_x+t_XO, card_loc_y+offset,  color, WHITE);
		      OCL_VIDEO_RenderText(video_ptr, "6", FONT_SIZE, screen_x + card_face_width / 2 - FONT_SIZE+b_XO, card_loc_y+card_face_high - FONT_SIZE+b_YO,  color, WHITE); 
		      break;
		   case 7:
		      suit_loc_x = card_center_x;
		      suit_loc_y = card_center_y-suit_h;
		      OCL_VIDEO_RenderImage(video_ptr, suit, suit_w, suit_h,  suit_loc_x, suit_loc_y);
		      suit_loc_x = card_center_x-suit_w;
		      suit_loc_y = card_center_y;
		      OCL_VIDEO_RenderImage(video_ptr, suit,  suit_w, suit_h, suit_loc_x, suit_loc_y);
		      suit_loc_x = card_center_x+suit_w;
		      suit_loc_y = card_center_y;
		      OCL_VIDEO_RenderImage(video_ptr, suit,  suit_w, suit_h, suit_loc_x, suit_loc_y);
		      suit_loc_x = card_center_x-suit_w;
		      suit_loc_y = card_center_y+suit_h+suit_h/2;
		      OCL_VIDEO_RenderImage(video_ptr, suit,  suit_w, suit_h, suit_loc_x, suit_loc_y);
		      suit_loc_x = card_center_x-suit_w;
		      suit_loc_y = card_center_y-suit_h-suit_h/2;
		      OCL_VIDEO_RenderImage(video_ptr, suit, suit_w, suit_h,  suit_loc_x, suit_loc_y);
		      suit_loc_x = card_center_x+suit_w;
		      suit_loc_y = card_center_y+suit_h+suit_h/2;
		      OCL_VIDEO_RenderImage(video_ptr, suit, suit_w, suit_h,  suit_loc_x, suit_loc_y);
		      suit_loc_x = card_center_x+suit_w;
		      suit_loc_y = card_center_y-suit_h-suit_h/2;
		      OCL_VIDEO_RenderImage(video_ptr, suit, suit_w, suit_h,  suit_loc_x, suit_loc_y);

		      OCL_VIDEO_RenderText(video_ptr, "7", FONT_SIZE, card_loc_x+t_XO, card_loc_y+offset,  color, WHITE);
		      OCL_VIDEO_RenderText(video_ptr, "7", FONT_SIZE, screen_x + card_face_width / 2 - FONT_SIZE+b_XO, card_loc_y+card_face_high - FONT_SIZE+b_YO,  color, WHITE); 
		      break;
		   case 8:
		      suit_loc_x = card_center_x-suit_w;
		      suit_loc_y = card_center_y+suit_h/2;
		      OCL_VIDEO_RenderImage(video_ptr, suit, suit_w, suit_h,  suit_loc_x, suit_loc_y);
		      suit_loc_x = card_center_x-suit_w;
		      suit_loc_y = card_center_y-suit_h/2;
		      OCL_VIDEO_RenderImage(video_ptr, suit, suit_w, suit_h,  suit_loc_x, suit_loc_y);
		      suit_loc_x = card_center_x+suit_w;
		      suit_loc_y = card_center_y+suit_h/2;
		      OCL_VIDEO_RenderImage(video_ptr, suit, suit_w, suit_h,  suit_loc_x, suit_loc_y);
		      suit_loc_x = card_center_x+suit_w;
		      suit_loc_y = card_center_y-suit_h/2;
		      OCL_VIDEO_RenderImage(video_ptr, suit, suit_w, suit_h,  suit_loc_x, suit_loc_y);

		      suit_loc_x = card_center_x-suit_w;
		      suit_loc_y = card_center_y+suit_h+suit_h/2;
		      OCL_VIDEO_RenderImage(video_ptr, suit,  suit_w, suit_h, suit_loc_x, suit_loc_y);
		      suit_loc_x = card_center_x-suit_w;
		      suit_loc_y = card_center_y-suit_h-suit_h/2;
		      OCL_VIDEO_RenderImage(video_ptr, suit, suit_w, suit_h,  suit_loc_x, suit_loc_y);
		      suit_loc_x = card_center_x+suit_w;
		      suit_loc_y = card_center_y+suit_h+suit_h/2;
		      OCL_VIDEO_RenderImage(video_ptr, suit, suit_w, suit_h,  suit_loc_x, suit_loc_y);
		      suit_loc_x = card_center_x+suit_w;
		      suit_loc_y = card_center_y-suit_h-suit_h/2;
		      OCL_VIDEO_RenderImage(video_ptr, suit, suit_w, suit_h,  suit_loc_x, suit_loc_y);

		      OCL_VIDEO_RenderText(video_ptr, "8", FONT_SIZE, card_loc_x+t_XO, card_loc_y+offset,  color, WHITE);
		      OCL_VIDEO_RenderText(video_ptr, "8", FONT_SIZE, screen_x + card_face_width / 2 - FONT_SIZE+b_XO, card_loc_y+card_face_high - FONT_SIZE+b_YO,  color, WHITE); 
		      break;
		   case 9:
		      suit_loc_x = card_center_x;
		      suit_loc_y = card_center_y;
		      OCL_VIDEO_RenderImage(video_ptr, suit, suit_w, suit_h,  suit_loc_x, suit_loc_y);

		      suit_loc_x = card_center_x-suit_w;
		      suit_loc_y = card_center_y+suit_h/2;
		      OCL_VIDEO_RenderImage(video_ptr, suit, suit_w, suit_h,  suit_loc_x, suit_loc_y);
		      suit_loc_x = card_center_x-suit_w;
		      suit_loc_y = card_center_y-suit_h/2;
		      OCL_VIDEO_RenderImage(video_ptr, suit,  suit_w, suit_h, suit_loc_x, suit_loc_y);
		      suit_loc_x = card_center_x+suit_w;
		      suit_loc_y = card_center_y+suit_h/2;
		      OCL_VIDEO_RenderImage(video_ptr, suit, suit_w, suit_h,  suit_loc_x, suit_loc_y);
		      suit_loc_x = card_center_x+suit_w;
		      suit_loc_y = card_center_y-suit_h/2;
		      OCL_VIDEO_RenderImage(video_ptr, suit,  suit_w, suit_h, suit_loc_x, suit_loc_y);

		      suit_loc_x = card_center_x-suit_w;
		      suit_loc_y = card_center_y+suit_h+suit_h/2;
		      OCL_VIDEO_RenderImage(video_ptr, suit, suit_w, suit_h,  suit_loc_x, suit_loc_y);
		      suit_loc_x = card_center_x-suit_w;
		      suit_loc_y = card_center_y-suit_h-suit_h/2;
		      OCL_VIDEO_RenderImage(video_ptr, suit, suit_w, suit_h,  suit_loc_x, suit_loc_y);
		      suit_loc_x = card_center_x+suit_w;
		      suit_loc_y = card_center_y+suit_h+suit_h/2;
		      OCL_VIDEO_RenderImage(video_ptr, suit, suit_w, suit_h,  suit_loc_x, suit_loc_y);
		      suit_loc_x = card_center_x+suit_w;
		      suit_loc_y = card_center_y-suit_h-suit_h/2;
		      OCL_VIDEO_RenderImage(video_ptr, suit, suit_w, suit_h,  suit_loc_x, suit_loc_y);

		      OCL_VIDEO_RenderText(video_ptr, "9", FONT_SIZE, card_loc_x+t_XO, card_loc_y+offset,  color, WHITE);
		      OCL_VIDEO_RenderText(video_ptr, "9", FONT_SIZE, screen_x + card_face_width / 2 - FONT_SIZE+b_XO, card_loc_y+card_face_high - FONT_SIZE+b_YO,  color, WHITE); 
		      break;
		   case 10:
		      suit_loc_x = card_center_x;
		      suit_loc_y = card_center_y+suit_h;
		      OCL_VIDEO_RenderImage(video_ptr, suit, suit_w, suit_h,  suit_loc_x, suit_loc_y);

		      suit_loc_x = card_center_x;
		      suit_loc_y = card_center_y-suit_h;
		      OCL_VIDEO_RenderImage(video_ptr, suit, suit_w, suit_h,  suit_loc_x, suit_loc_y);

		      suit_loc_x = card_center_x-suit_w;
		      suit_loc_y = card_center_y+suit_h/2;
		      OCL_VIDEO_RenderImage(video_ptr, suit, suit_w, suit_h,  suit_loc_x, suit_loc_y);
		      suit_loc_x = card_center_x-suit_w;
		      suit_loc_y = card_center_y-suit_h/2;
		      OCL_VIDEO_RenderImage(video_ptr, suit, suit_w, suit_h,  suit_loc_x, suit_loc_y);
		      suit_loc_x = card_center_x+suit_w;
		      suit_loc_y = card_center_y+suit_h/2;
		      OCL_VIDEO_RenderImage(video_ptr, suit, suit_w, suit_h,  suit_loc_x, suit_loc_y);
		      suit_loc_x = card_center_x+suit_w;
		      suit_loc_y = card_center_y-suit_h/2;
		      OCL_VIDEO_RenderImage(video_ptr, suit, suit_w, suit_h,  suit_loc_x, suit_loc_y);

		      suit_loc_x = card_center_x-suit_w;
		      suit_loc_y = card_center_y+suit_h+suit_h/2;
		      OCL_VIDEO_RenderImage(video_ptr, suit, suit_w, suit_h,  suit_loc_x, suit_loc_y);
		      suit_loc_x = card_center_x-suit_w;
		      suit_loc_y = card_center_y-suit_h-suit_h/2;
		      OCL_VIDEO_RenderImage(video_ptr, suit, suit_w, suit_h,  suit_loc_x, suit_loc_y);
		      suit_loc_x = card_center_x+suit_w;
		      suit_loc_y = card_center_y+suit_h+suit_h/2;
		      OCL_VIDEO_RenderImage(video_ptr, suit, suit_w, suit_h,  suit_loc_x, suit_loc_y);
		      suit_loc_x = card_center_x+suit_w;
		      suit_loc_y = card_center_y-suit_h-suit_h/2;
		      OCL_VIDEO_RenderImage(video_ptr, suit, suit_w, suit_h,  suit_loc_x, suit_loc_y);

		      OCL_VIDEO_RenderText(video_ptr, "10", FONT_SIZE, card_loc_x+t_XO, card_loc_y+offset,  color, WHITE);
		      OCL_VIDEO_RenderText(video_ptr, "10", FONT_SIZE, screen_x + card_face_width / 2 - FONT_SIZE-FONT_SIZE/2+b_XO, card_loc_y+card_face_high - FONT_SIZE+b_YO,  color, WHITE); 
		      break;
		   case JACK:
		      suit_loc_x = screen_x -jack_width/2;
		      suit_loc_y = screen_y-jack_high/2;
		      OCL_VIDEO_RenderImage(video_ptr, &jack_img, jack_width, jack_high,  suit_loc_x, suit_loc_y);

		      suit_loc_x = card_center_x-suit_w;
		      suit_loc_y = card_center_y-suit_h-suit_h/2;
		      OCL_VIDEO_RenderImage(video_ptr, suit, suit_w, suit_h,  suit_loc_x, suit_loc_y);

		      suit_loc_x = card_center_x+suit_w;
		      suit_loc_y = card_center_y+suit_h+suit_h/2;
		      OCL_VIDEO_RenderImage(video_ptr, suit, suit_w, suit_h,  suit_loc_x, suit_loc_y);

		      OCL_VIDEO_RenderText(video_ptr, "J", FONT_SIZE, card_loc_x+t_XO, card_loc_y+offset,  color, WHITE);
		      OCL_VIDEO_RenderText(video_ptr, "J", FONT_SIZE, screen_x + card_face_width / 2 - FONT_SIZE+b_XO, card_loc_y+card_face_high - FONT_SIZE+b_YO,  color, WHITE); 
		      break;
		   case QUEEN:
		      suit_loc_x = screen_x -queen_width/2;
		      suit_loc_y = screen_y-queen_high/2;
		      OCL_VIDEO_RenderImage(video_ptr, &queen_img, queen_width, queen_high,  suit_loc_x, suit_loc_y);

		      suit_loc_x = card_center_x-suit_w;
		      suit_loc_y = card_center_y-suit_h-suit_h/2;
		      OCL_VIDEO_RenderImage(video_ptr, suit, suit_w, suit_h,  suit_loc_x, suit_loc_y);

		      suit_loc_x = card_center_x+suit_w;
		      suit_loc_y = card_center_y+suit_h+suit_h/2;
		      OCL_VIDEO_RenderImage(video_ptr, suit, suit_w, suit_h,  suit_loc_x, suit_loc_y);

		      OCL_VIDEO_RenderText(video_ptr, "Q", FONT_SIZE, card_loc_x+t_XO, card_loc_y+offset,  color, WHITE);
		      OCL_VIDEO_RenderText(video_ptr, "Q", FONT_SIZE, screen_x + card_face_width / 2 - FONT_SIZE+b_XO, card_loc_y+card_face_high - FONT_SIZE+b_YO,  color, WHITE); 
		      break;
		   case KING:
		      suit_loc_x = screen_x -king_width/2;
		      suit_loc_y = screen_y -king_high/2;
		      OCL_VIDEO_RenderImage(video_ptr, &king_img, king_width, king_high,  suit_loc_x, suit_loc_y);

		      suit_loc_x = card_center_x-suit_w;
		      suit_loc_y = card_center_y-suit_h-suit_h/2;
		      OCL_VIDEO_RenderImage(video_ptr, suit, suit_w, suit_h,  suit_loc_x, suit_loc_y);

		      suit_loc_x = card_center_x+suit_w;
		      suit_loc_y = card_center_y+suit_h+suit_h/2;
		      OCL_VIDEO_RenderImage(video_ptr, suit, suit_w, suit_h,  suit_loc_x, suit_loc_y);

		      OCL_VIDEO_RenderText(video_ptr, "K", FONT_SIZE, card_loc_x+t_XO, card_loc_y+offset,  color, WHITE);
		      OCL_VIDEO_RenderText(video_ptr, "K", FONT_SIZE, screen_x + card_face_width / 2 - FONT_SIZE +b_XO, card_loc_y+card_face_high - FONT_SIZE+b_YO,  color, WHITE); 
		      break;
		   default:
		      break;
		}
	}
	else
	{
		printf("Error! Null value in CARDS_RenderCard\n");
	}
	
}

void CARDS_GetNewDeck(CARDS_Deck *deck)
{
   int suit = 0;
   int value = 0;

   if(deck != NULL)
   {
	   deck->card_count = 52;
	   for(value = 0; value < 52; value++)
	   {
	      deck->card[value].suit  = suit;
	      deck->card[value].value = (value%13)+2;
	      
	      if((value+1)%13 == 0)suit++;	   }
   }
   else
   {
      printf("ERROR! Null Deck in CARDS_GetNewDeck\n");
   }
}

void CARDS_Shuffle(CARDS_Deck *deck)
{
   int card[52];
   int i=0;
   int r = 0;
   CARDS_Card tCard;

   if(deck != NULL)
   {
	   srand(time(0));

	   for(i=0; i<(deck->card_count-1); i++) 
	   {
	      r = i +(rand() % (deck->card_count-i));
	      tCard = deck->card[i];
	      deck->card[i] = deck->card[r];
	      deck->card[r] = tCard;
	   }
   }
   else
   {
      printf("ERROR! Null Deck in CARDS_Shuffle\n");
   }
}

int CARDS_DealCard(CARDS_Deck *deck, CARDS_Card *card)
{

   if(deck != NULL && card != NULL)
   {

	   if(deck->card_count > 0)
	   {
	      card->suit = deck->card[52-deck->card_count].suit;
	      card->value = deck->card[52-deck->card_count].value;

	      deck->card_count = deck->card_count -1;
	      return 0;
	   }
	   else
	   {
	      return 1;  //Return 1 b/c pile was empty
	   }
   }
   else
   {
      printf("ERROR! Null Deck or card in CARDS_DealCard\n");
      return 1;
   }
   
}

//Adds 'card' back to the end of the deck
void CARDS_Discard(CARDS_Deck *deck, CARDS_Card card)
{
   if(deck != NULL)
   {
      deck->card[deck->card_count] = card;
   }
   else
   {
      printf("ERROR! Null Deck in CARDS_Discard\n");
   }
   
}

//Gaming Functions
CARDS_PairListType  CARDS_GetHandPairs(const CARDS_Card *hand, const int hand_size)
{
   //returns list of Pair sets
   int i = 0;
   int j = 0;

   int found = 0;

   CARDS_PairListType pairList;

   pairList.pair = malloc(hand_size * sizeof(CARDS_PairType));
   for(;i<hand_size;i++)
   {
      pairList.pair[i].value = 0;
      pairList.pair[i].count = 0;
   }
   pairList.size = 0;

   i=0;

   for(;i<hand_size;i++)
   {  
      j=0;
      found=0;   
      while(j<hand_size && !found)
      {
         if(pairList.pair[j].value == hand[i].value)
         {
            pairList.pair[j].count++;
            found = 1;
         }
         else if(pairList.pair[j].value == 0)
         {
            pairList.pair[j].value = hand[i].value;
            pairList.pair[j].count++;
            found = 1;
            pairList.size++;
         }

         j++;
      }
   }

   return pairList;
      
}

int CARDS_IsCardClicked(const CARDS_Card card, int screen_x, int screen_y)
{

   if(((screen_x > card.screen_loc_x) & (screen_x < (card.screen_loc_x + card.screen_loc_w))) &&
		((screen_y > card.screen_loc_y) & (screen_y < (card.screen_loc_y + card.screen_loc_h))))
   {
         return 1;
   }

   return 0;
}

int CARDS_IsFlushHand(const CARDS_Card *hand, const int hand_size)
{
   //returns 0 if no flush, else 1
   int i = 0;

   for(;i<hand_size-1;i++)
   {
      if(hand[i].suit != hand[i+1].suit) return 0;
   }

   return 1;
}

int CARDS_IsStraightHand(const CARDS_Card *hand, const int hand_size)
{
   //returns 0 if no straight, else 1
   int i=0;
   CARDS_Card *tHand = malloc(hand_size * (sizeof(CARDS_Card)));

   for(;i<hand_size;i++)
       tHand[i] = hand[i];

   CARDS_SortHand(tHand, hand_size);

   i=0;

   for(;i<hand_size-1;i++)
   {
     if(tHand[i].value != (tHand[i+1].value - 1)) return 0;
   }

   free(tHand);

   return 1;
}

void CARDS_SortHand(CARDS_Card *hand, const int hand_size)
{
    //sorts hand from low to high
    //Stupid bubble sort for now
    int i=0;
    int j=0;

    CARDS_Card tCard;

    for(;i<hand_size-1;i++)
    {
        for(;j<hand_size-i-1;j++)
        {
           if(hand[j].value > hand[j+1].value)
           {
              tCard = hand[j];
              hand[j] = hand[j+1];
              hand[j+1] = tCard;
           }
        }
     }

}

CARDS_PokerHandType CARDS_GetPokerHandType(CARDS_Card *hand, int total_hand_size, int cards_to_use)
{
   //TODO extend for case where cards_to_use is greater than hand size (Texas holdem)

   int pair_count=0;
   int three_of_a_kind_count=0;
   int four_of_a_kind_count=0;
   int isFlush=0;
   int isStraight=0;
   int jacks_or_better=0;
   int i=0;
 
   CARDS_PokerHandType retType = HIGH_CARD;

   CARDS_PairListType pairs = CARDS_GetHandPairs(hand, total_hand_size);

   for(i = 0; i < pairs.size; i++)
   {
      if(pairs.pair[i].count == 2)
      {
         if(pairs.pair[i].value >= JACK) jacks_or_better = 1;
         pair_count++;
      }
      else if(pairs.pair[i].count == 3)
      {
         three_of_a_kind_count++;
      }
      else if(pairs.pair[i].count == 4)
      {
         retType =  FOUR_OF_A_KIND;
      }
   }

   if(pair_count == 2)  retType =  TWO_PAIR;
   else if(pair_count == 1 && three_of_a_kind_count == 1) retType =  FULL_HOUSE;
   else if(pair_count == 1 && jacks_or_better) retType = ONE_PAIR_JACKS_OR_BETTER;
   else if(pair_count == 1) retType = ONE_PAIR;
   else if(three_of_a_kind_count == 1) retType =  THREE_OF_A_KIND;

   //check for flush
   isFlush = CARDS_IsFlushHand(hand, total_hand_size);

   isStraight = CARDS_IsStraightHand(hand, total_hand_size);

   if(isFlush && isStraight && hand[cards_to_use].value == ACE) retType =  ROYAL_FLUSH;
   else if(isFlush && isStraight) retType =  STRAIGHT_FLUSH;
   else if(isFlush) retType =  FLUSH;
   else if(isStraight) retType =  STRAIGHT;

   free(pairs.pair);

   return retType;
   
}

//Returns 0 if hand_0 is better
//Returns 1 if hand_1 is better
//Returns 2 if hands are equal
int CARDS_ComparePokerHand(CARDS_Card *hand_0, int hand_0_size, CARDS_Card *hand_1, int hand_1_size)
{

}
